package com.wuercloud.mq.message.conf;

import com.wuercloud.mq.message.converter.FastJsonMessageConverter;
import com.wuercloud.mq.message.listener.MessageHandlerListener;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitManagementTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.web.client.RestTemplate;

/**
 * Created by JiangWL on 2017/4/5.
 */
@Configuration
@ComponentScan("com.wuercloud.mq")
public class ConsumerConfiguration {
    @Autowired
    private Environment environment;

    @Bean("restClientTemplate")
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Autowired
    private FastJsonMessageConverter fastJsonMessageConverter;
    @Autowired
    private ConnectionFactory rabbitConnectionFactory;
    @Autowired
    private RabbitAdmin rabbitAdmin;

    /**
     * rabbitmq管理器，可以对队列进行管理，调用其rest
     * @return
     */
    @Bean
    public RabbitManagementTemplate rabbitManagementTemplate() {
        RabbitManagementTemplate rabbitManagementTemplate = new RabbitManagementTemplate(
                environment.getProperty("rabbitmq-manage-url"),
                environment.getProperty("rabbitmq-Username"),
                environment.getProperty("rabbitmq-Password"));
        return rabbitManagementTemplate;
    }

    /**
     * 本段代码暂不使用，消费端可以采用去处理业务
     * @return
     */
    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer(){
        SimpleMessageListenerContainer messageListenerContainer = new SimpleMessageListenerContainer(rabbitConnectionFactory);
        //手动确认使用
        messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        //messageListenerContainer.setConcurrentConsumers(Runtime.getRuntime().availableProcessors()/);
        messageListenerContainer.setMaxConcurrentConsumers(Runtime.getRuntime().availableProcessors()/2);
        messageListenerContainer.setConcurrentConsumers(Integer.parseInt(environment.getProperty("rabbitmq-ConcurrentConsumers")));
        //messageListenerContainer.setMaxConcurrentConsumers(Integer.parseInt(environment.getProperty("rabbitmq-MaxConcurrentConsumers")));
        messageListenerContainer.setPrefetchCount(1);

        messageListenerContainer.setMessageListener(messageHandlerListener());
        messageListenerContainer.setMessageConverter(fastJsonMessageConverter);
        messageListenerContainer.setRabbitAdmin(rabbitAdmin);
        SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(environment.getProperty("rabbitmq-ThreadNamePrefix").concat("-MsgListener ### ::"));
        //taskExecutor.setConcurrencyLimit(Integer.parseInt(environment.getProperty("rabbitmq-ConcurrencyLimit")));
        taskExecutor.setConcurrencyLimit(Runtime.getRuntime().availableProcessors());
        messageListenerContainer.setTaskExecutor(taskExecutor);
        return messageListenerContainer;
    }


    /**
     * 失败重试发送模板，其他template需用时要注入此bean
     * 如：template.setRetryTemplate(retryTemplate);
     * retryTemplate需要在业务类中@Autowired
     * @return
     */
   /* @Bean
    public RetryTemplate retryTemplate(){
        RetryTemplate retryTemplate = new RetryTemplate(){
            @Override
            public void setBackOffPolicy(BackOffPolicy backOffPolicy) {
                ExponentialBackOffPolicy policy = new ExponentialBackOffPolicy();
                *//*
                    失败重试机制，发送失败之后，会尝试重发三次，重发间隔(ms)为
                    第一次 initialInterval
                    此后：initialInterval*multiplier > maxInterval ? maxInterval : initialInterval*multiplier。
                    配合集群使用的时候，当mq集群中一个down掉之后，重试机制尝试其他可用的mq。
                    API默认为：
                        private volatile long initialInterval = 100L;
                        private volatile long maxInterval = 30000L;
                        private volatile double multiplier = 2.0D;
                *//*
                policy.setInitialInterval(Integer.parseInt(environment.getProperty("backOffPolicy.initialInterval")));
                policy.setMultiplier(Integer.parseInt(environment.getProperty("backOffPolicy.multiplier")));
                policy.setMaxInterval(Integer.parseInt(environment.getProperty("backOffPolicy.maxInterval")));

            }
        };
        return retryTemplate;
    }*/

    @Bean
    public MessageHandlerListener messageHandlerListener(){
        return new MessageHandlerListener();
    }

}
